package com.strongbj.iot.devices.newlight.response.handle;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.strongbj.core.util.ByteUtil;
import com.strongbj.core.util.ContextUtils;
import com.strongbj.iot.devices.newlight.common.Executer;
import com.strongbj.iot.devices.newlight.entity.Reader;
import com.strongbj.iot.devices.newlight.entity.T;
import com.strongbj.iot.devices.newlight.entity.Tag;
import com.strongbj.iot.devices.newlight.message.NewLightOSMessageFactory;
import com.strongbj.iot.devices.newlight.message.NewLightReaderMessage;
import com.strongbj.iot.devices.newlight.response.AbstractMessageReturnHandle;
import com.strongbj.iot.devices.newlight.service.ReaderService;
import com.strongbj.iot.devices.newlight.service.TagService;

import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled;
import io.netty.channel.ChannelHandlerContext;

/**
 * 收到4B命令重新绑定失败标签的处理
 * 
 * @author yuzhantao
 *
 */
public class ReBindTagHandle extends AbstractMessageReturnHandle {
	private static Logger logger = LogManager.getLogger(AutoInventoryCtrlResponseHandle.class.getName());
	private ReaderService readerService = (ReaderService) ContextUtils.getBean("readerService");
	private TagService tagService = (TagService) ContextUtils.getBean("tagService");
	private NewLightOSMessageFactory newLightOSMessageFactory = (NewLightOSMessageFactory) ContextUtils
			.getBean("newLightOSMessageFactory");

	private ExecutorService theadPool = Executors.newSingleThreadExecutor();
	private static final byte REBIND_TAG_TYPE = Integer.valueOf("4B", 16).byteValue();
	private static final String EMPTY_SHORT_ADDRESS = "0000";

	@Override
	public boolean isHandle(NewLightReaderMessage t) {
		if (REBIND_TAG_TYPE == t.getType()) {
			return true;
		} else {
			return false;
		}
	}

	@Override
	public Object dataHandle(ChannelHandlerContext ctx, NewLightReaderMessage t) {
		logger.info("====收到绑签失败后0X4B指令====");
		QueryWrapper<Tag> wrapper = new QueryWrapper<Tag>();
		wrapper.eq("short_address", EMPTY_SHORT_ADDRESS);
		wrapper.or().isNull("short_address");
		List<Tag> tags = tagService.list(wrapper);
		for (int i = 0; i < tags.size(); i++) {
			theadPool.execute(new TagBindRunnable(tags.get(i)));
		}
		return null;
	}

	@Override
	public String getHandleName() {
		return "重绑标签";
	}
	
	@Override
	public void destory() {
		if (this.theadPool != null) {
			this.theadPool.shutdown();
		}
	}

	/**
	 * 标签绑定处理
	 * 
	 * @author yuzhantao
	 *
	 */
	class TagBindRunnable implements Runnable {
		private Tag tag;

		public TagBindRunnable(Tag tag) {
			this.tag = tag;
		}

		@Override
		public void run() {
			int count = 3;

			while (count-- > 0 && isBinding(this.tag.getIp()) == false) {
				if (this.tag == null)
					return;
				QueryWrapper<Reader> wrapper = new QueryWrapper<Reader>();
				wrapper.eq("code_", this.tag.getReader());
				Reader reader = readerService.getOne(wrapper);
				if (reader == null) {
					logger.info("未从数据库中找到指定设备，无法重绑标签 设备编号:{}", this.tag.getReader());
					return;
				}

				this.sendBindTagCommand(reader.getIp(), reader.getCode(), this.tag.getIp());

				try {
					Thread.sleep(30000);
				} catch (InterruptedException e) {
					e.printStackTrace();
				}
			}
		}

		/**
		 * 标签是否已绑定
		 * 
		 * @param tag
		 * @return
		 */
		private boolean isBinding(String tag) {
			QueryWrapper<Tag> wrapper = new QueryWrapper<Tag>();
			wrapper.eq("ip_", tag);
			wrapper.eq("short_address", EMPTY_SHORT_ADDRESS);
			return tagService.getOne(wrapper) == null;
		}

		/**
		 * 发送绑签命令
		 * 
		 * @param deviceIp
		 * @param deviceCode
		 * @param tag
		 */
		private void sendBindTagCommand(String deviceIp, String deviceCode, String tag) {
			byte[] sendData = new byte[6];
			byte[] d = ByteUtil.ipToBytesByInet(tag);
			System.arraycopy(d, 0, sendData, 0, 4);
			sendData[4] = 0x3e;
			sendData[5] = 0x00;
			byte[] req = newLightOSMessageFactory.createNewLightOSMessage(ByteUtil.addressToBytes(deviceCode),
					(byte) 0x02, sendData, T.getTimeStamp());
			ByteBuf bs = Unpooled.copiedBuffer(req);
			
			//使用队列发送命令
			Map<String,Object> args = new HashMap<String,Object>();
			args.put("code", deviceCode);
			args.put("tag", tag);
			args.put("req", req);
			Executer.RunCmd("BindTag", deviceCode, bs, args, T.getTimeStamp());
			
//			Channel channel = NetMapping.getInstance().getChannel(deviceIp);
//
//			Preconditions.checkNotNull(channel,
//					"设备未连接,无法发送补邦命令,设备编号=" + deviceCode + "  ip=" + deviceIp + "  标签编号=" + tag);
//			ChannelFuture cf = channel.writeAndFlush(bs);
//			cf.addListener(new ChannelFutureListener() {
//				@Override
//				public void operationComplete(ChannelFuture future) throws Exception {
//					if (future.isSuccess()) {
//						logger.info("发送绑签命令成功 设备编号:{} ip:{} 标签编号:{}", deviceCode, deviceIp, tag);
//					} else {
//						logger.debug("发送绑签命令失败 设备编号:{} ip:{} 标签编号:{}", deviceCode, deviceIp, tag);
//					}
//				}
//
//			});
		}
	}
}
